package com.steve.combat.thread.多线程交替打印ABC;

/**
 * @Author: STEVE
 * @Description: 使用wait()和notify()
 * @since: 2025-06-01
 */
public class PrintABCUsingWaitNotify {

    /**
     * 实现步骤：
     * 定义一个共享对象用来同步。
     * 使用wait()让线程进入等待状态。
     * 使用notify()唤醒下一个线程。
     */

    private final Object lock = new Object();
    private int state = 0;  // 0:A 1:B 2:C

    public static void main(String[] args) {
        PrintABCUsingWaitNotify task = new PrintABCUsingWaitNotify();

        Thread threadA = new Thread(task::printA);
        Thread threadB = new Thread(task::printB);
        Thread threadC = new Thread(task::printC);

        threadA.start();
        threadB.start();
        threadC.start();
    }

    public void printA() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                while (state != 0) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print("A");
                state = 1;
                lock.notifyAll();
            }
        }
    }

    public void printB() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                while (state != 1) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print("B");
                state = 2;
                lock.notifyAll();
            }
        }
    }

    public void printC() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                while (state != 2) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print("C");
                state = 0;
                lock.notifyAll();
            }
        }
    }

}
